<template>
    <div class="vue-table-container">
        <div v-if="searchConfig.status" class="search-box row">
            <div class="col mr-auto">
                <slot name="search" :items="searchConfig.items"></slot>
            </div>
            <div class="col-auto">
                <Tooltip content="高级检索" v-if="searchConfig.complex" placement="top">
                    <i-button type="text" @click="openComplex">
                        <Icon :type="complexOpen ? 'chevron-up' : 'chevron-down'" size="18"></Icon>
                    </i-button>
                </Tooltip>
                <i-button type="primary" icon="ios-search" @click="search">检索</i-button>
            </div>
        </div>
        <div class="table-container">
            <table class="table table-hover" id='hl-tree-table'>
                <thead>
                <tr>
                    <th v-for="(column,index) in cloneColumns">
                        <label v-if="column.type === 'selection'">
                            <input type="checkbox" v-model="checks" @click="handleCheckAll">
                        </label>
                        <label v-else>
                            {{ renderHeader(column, index) }}

                        </label>
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="(item,index) in initItems" :key="item.id" v-show="show(item)" :class="{'child-tr':item.parent}">
                    <td v-for="(column,snum) in columns" :key="column.key" :style=tdStyle(column)>
                        <label v-if="column.type === 'selection'">
                            <input type="checkbox" :value="item.id" v-model="checkGroup">
                        </label>
                        <div v-if="column.type === 'action'">
                            <Tooltip :content="getContent(action.text)" placement="top"  v-for='action in (column.actions)' :key="action.text">
                                <i-button :type="action.type" size="small" @click="RowClick(item,action.text)" >

                                    <Icon :type="action.icon" size="16"></Icon>
                                </i-button>
                            </Tooltip>

                        </div>
                        <label @click="toggle(index,item)" v-if="!column.type" :style=labStyle(column,item)>
                            <span v-if='snum==iconRow()'>
                                <i v-html='item.spaceHtml'></i>
                                <i v-if="item.children&&item.children.length>0" class="ivu-icon" :class="{'ivu-icon-arrow-right-b':!item.expanded,'ivu-icon-arrow-down-b':item.expanded }"></i>
                                <i v-else class="ms-tree-space"></i>
                            </span> {{renderBody(item,column) }}
                        </label>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
        <!--<div class="widget-toolbox padding-10 clearfix">-->
        <!--<pagination :page-count="dataSource.pageCount"-->
        <!--:total="dataSource.total"-->
        <!--:current-page="dataSource.currentPage" @goPage="goPage"></pagination>-->
        <!--</div>-->
    </div>
</template>
<script>
  export default {
    props: {
      columns: Array,
      items: {
        type: Array,
        default: function() {
          return [];
        }
      },
      searchConfig: {
        type: Object,
        default: {
          status: false,
          items: {},
          complex: false
        }
      }
    },
    data() {
      return {
        complexOpen: false,
        initItems: [], //处理后数据数组
        cloneColumns: [], //处理后的表头数据
        checkGroup: [], //复选框数组
        checks: false, //全选
        screenWidth: document.body.clientWidth, //自适应宽
        tdsWidth: 0, //td总宽
        timer: false, //控制监听时长
        dataLength: 0, //树形数据长度
      }
    },
    computed: {
      tableWidth() {
        return this.tdsWidth > this.screenWidth && this.screenWidth > 0 ? this.screenWidth + 'px' : '100%'
      }
    },
    watch: {
      screenWidth(val) {
        if (!this.timer) {
          this.screenWidth = val
          this.timer = true
          setTimeout(() => {
            this.timer = false
          }, 400)
        }
      },
      items() {
        if (this.items) {
          this.dataLength = this.Length(this.items)
          this.initData(this.deepCopy(this.items), 1, null);
          this.checkGroup = this.renderCheck(this.items)
          if (this.checkGroup.length == this.dataLength) {
            this.checks = true
          } else {
            this.checks = false
          }
        }
      },
      columns: {
        handler() {
          this.cloneColumns = this.makeColumns();
        },
        deep: true
      },
      checkGroup(data) {
        this.checkAllGroupChange(data)
      },
    },
    mounted() {
      if (this.items) {
        this.dataLength = this.Length(this.items)
        this.initData(this.deepCopy(this.items), 1, null);
        this.cloneColumns = this.makeColumns();
        this.checkGroup = this.renderCheck(this.items)
        if (this.checkGroup.length == this.dataLength) {
          this.checks = true
        } else {
          this.checks = false
        }
      }
      // 绑定onresize事件 监听屏幕变化设置宽
      this.$nextTick(() => {
        this.screenWidth = document.body.clientWidth
      })
      window.onresize = () => {
        return (() => {
          window.screenWidth = document.body.clientWidth
          this.screenWidth = window.screenWidth
        })()
      }
    },
    methods: {
      getContent:function (content) {
        switch (content){
          case 'edit':
            return '编辑';
          case 'delete':
            return '删除';
          case 'son':
            return '添加子项';
          default:
            return content
        }
      },
      search: function () {
        let self = this;
        this.$emit('on-query', self.searchConfig.items);
      },
      goPage: function (event) {
        let self = this;
        let query = _.assign({page: event.page}, self.searchConfig.items);
        this.$emit('on-query', query);
      },
      openComplex: function () {
        if (this.complexOpen) {
          this.complexOpen = false;
        } else {
          this.complexOpen = true;
        }
        this.$emit('open-complex', this.complexOpen);
      },
      // 有无多选框折叠位置优化
      iconRow() {
        for (var i = 0, len = this.columns.length; i < len; i++) {
          if (this.columns[i].type == 'selection') {
            return 1
          }
        }
        return 0
      },
      // 设置td宽度,td的align
      tdStyle(column) {
        var style = {}
        if (column.align) {
          style["text-align"] = column.align;
        }
        if (column.width) {
          style["min-width"] = column.width + 'px';
        }
        return style;
      },
      labStyle(column,item){
        var style = {}
        if (column.head ) {
          style["padding-left"] = item.level*9 +'px';
        }
        return style;
      },
      // 排序事件
      handleSort(index, type) {
        this.cloneColumns.forEach((col) => col._sortType = 'normal');
        if (this.cloneColumns[index]._sortType === type) {
          this.cloneColumns[index]._sortType = 'normal'
        } else {
          this.cloneColumns[index]._sortType = type
        }
        this.$emit('on-sort-change', this.cloneColumns[index]['key'], this.cloneColumns[index]['_sortType'])
      },
      // 点击某一行事件
      RowClick(data, event, index, text) {
        let result = this.makeData(data)
        this.$emit('on-row-click', result, event, index, text)
      },
      // 点击事件 返回数据处理
      makeData(data) {
        const t = this.type(data);
        let o;
        if (t === 'array') {
          o = [];
        } else if (t === 'object') {
          o = {};
        } else {
          return data;
        }
        if (t === 'array') {
          for (let i = 0; i < data.length; i++) {
            o.push(this.makeData(data[i]));
          }
        } else if (t === 'object') {
          for (let i in data) {
            if (i != 'spaceHtml' && i != 'parent' && i != 'level' && i != 'expanded' && i != 'isShow' && i !=
              'load') {
              o[i] = this.makeData(data[i]);
            }
          }
        }
        return o;
      },
      // 处理表头数据
      makeColumns() {
        let columns = this.deepCopy(this.columns);
        this.tdsWidth = 0
        columns.forEach((column, index) => {
          column._index = index;
          column._width = column.width ? column.width : '';
          column._sortType = 'normal';
          this.tdsWidth += column.width ? parseFloat(column.width) : 0;
        });
        return columns;
      },
      // 数据处理 增加自定义属性监听
      initData(items, level, parent) {
        this.initItems = []
        let spaceHtml = "";
        for (var i = 1; i < level; i++) {
          spaceHtml += "<i class='ms-tree-space'></i>"
        }
        items.forEach((item, index) => {
          item = Object.assign({}, item, {
            "parent": parent,
            "level": level,
            "spaceHtml": spaceHtml
          });
          if ((typeof item.expanded) == "undefined") {
            item = Object.assign({}, item, {
              "expanded": false
            });
          }
          if ((typeof item.show) == "undefined") {
            item = Object.assign({}, item, {
              "isShow": false
            });
          }
          item = Object.assign({}, item, {
            "load": (item.expanded ? true : false)
          });
          this.initItems.push(item);
          if (item.children && item.expanded) {
            this.initData(item.children, level + 1, item);
          }
        })
      },
      //  隐藏显示
      show(item) {
        return ((item.level == 1) || (item.parent && item.parent.expanded && item.isShow));
      },
      toggle(index, item) {
        let level = item.level + 1;
        let spaceHtml = "";
        for (var i = 1; i < level; i++) {
          spaceHtml += "<i class='ms-tree-space'></i>"
        }
        if (item.children) {
          if (item.expanded) {
            item.expanded = !item.expanded;
            this.close(index, item);
          } else {
            item.expanded = !item.expanded;
            if (item.load) {
              this.open(index, item);
            } else {
              item.load = true;
              item.children.forEach((child, childIndex) => {
                this.initItems.splice((index + childIndex + 1), 0, child);
                //设置监听属性
                this.$set(this.initItems[index + childIndex + 1], 'parent', item);
                this.$set(this.initItems[index + childIndex + 1], 'level', level);
                this.$set(this.initItems[index + childIndex + 1], 'spaceHtml', spaceHtml);
                this.$set(this.initItems[index + childIndex + 1], 'isShow', true);
                this.$set(this.initItems[index + childIndex + 1], 'expanded', false);
              })
            }
          }
        }
      },
      open(index, item) {
        if (item.children) {
          item.children.forEach((child, childIndex) => {
            child.isShow = true;
            if (child.children && child.expanded) {
              this.open(index + childIndex + 1, child);
            }
          })
        }
      },
      close(index, item) {
        if (item.children) {
          item.children.forEach((child, childIndex) => {
            child.isShow = false;
            child.expanded = false;
            if (child.children) {
              this.close(index + childIndex + 1, child);
            }
          })
        }
      },
      //checkbox 全选 选择事件
      handleCheckAll() {
        this.checks = !this.checks;
        if (this.checks) {
          this.checkGroup = this.getArray(this.checkGroup.concat(this.All(this.items)))
        } else {
          this.checkGroup = []
        }
        // this.$emit('on-selection-change', this.checkGroup)
      },
      // 数组去重
      getArray(a) {
        var hash = {},
          len = a.length,
          result = [];
        for (var i = 0; i < len; i++) {
          if (!hash[a[i]]) {
            hash[a[i]] = true;
            result.push(a[i]);
          }
        }
        return result;
      },
      checkAllGroupChange(data) {
        if (this.dataLength > 0 && data.length === this.dataLength) {
          this.checks = true;
        } else {
          this.checks = false;
        }
        this.$emit('on-selection-change', this.checkGroup)
      },
      All(data) {
        let arr = []
        data.forEach((item) => {
          arr.push(item.id)
          if (item.children && item.children.length > 0) {
            arr = arr.concat(this.All(item.children));
          }
        })
        return arr
      },
      // 返回树形数据长度
      Length(data) {
        let length = data.length
        data.forEach((child) => {
          if (child.children) {
            length += this.Length(child.children)
          }
        })
        return length;
      },
      // 返回表头
      renderHeader(column, $index) {
        if ('renderHeader' in this.columns[$index]) {
          return this.columns[$index].renderHeader(column, $index);
        } else {
          return column.title || '#';
        }
      },
      // 返回内容
      renderBody(row, column, index) {
        return row[column.key]
      },
      // 默认选中
      renderCheck(data) {
        let arr = []
        data.forEach((item) => {
          if (item._checked) {
            arr.push(item.id)
          }
          if (item.children && item.children.length > 0) {
            arr = arr.concat(this.renderCheck(item.children));
          }
        })
        return arr
      },
      // 深度拷贝函数
      deepCopy(data) {
        var t = this.type(data),
          o, i, ni;
        if (t === 'array') {
          o = [];
        } else if (t === 'object') {
          o = {};
        } else {
          return data;
        }
        if (t === 'array') {
          for (i = 0, ni = data.length; i < ni; i++) {
            o.push(this.deepCopy(data[i]));
          }
          return o;
        } else if (t === 'object') {
          for (i in data) {
            o[i] = this.deepCopy(data[i]);
          }
          return o;
        }
      },
      type(obj) {
        var toString = Object.prototype.toString;
        var map = {
          '[object Boolean]': 'boolean',
          '[object Number]': 'number',
          '[object String]': 'string',
          '[object Function]': 'function',
          '[object Array]': 'array',
          '[object Date]': 'date',
          '[object RegExp]': 'regExp',
          '[object Undefined]': 'undefined',
          '[object Null]': 'null',
          '[object Object]': 'object'
        };
        return map[toString.call(obj)];
      }
    },
    beforeDestroy() {
      window.onresize = null
    }
  }
</script>
<style scoped lang="scss">
    .search-box {
        /*width: 90%;*/
        height: auto;
        margin: 15px auto;
        .col {
            padding-left: 0;
        }
        .col-auto {
            padding-right: 0;
        }
    }

    .table-container {
        text-align: center;
        font-size: 13px;
        .table {
            th, td {
                padding: 0.5rem;
                vertical-align: middle !important;
            }
            td {
                padding: 9px 9px;
            }
        }
    }
</style>